using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Net;
using System.IO;
using System.Collections.Specialized;
using System.Security.Cryptography;
using System.Text;


public class oAuthOrkut : oAuthBase2
{
    public enum Method { GET, POST, PUT, DELETE };
    public const string REQUEST_TOKEN = "https://www.google.com/accounts/OAuthGetRequestToken";
    public const string AUTHORIZE = "https://www.google.com/accounts/OAuthAuthorizeToken";
    public const string ACCESS_TOKEN = "https://www.google.com/accounts/OAuthGetAccessToken";
    public const string SCOPE = "http://sandbox.orkut.gmodules.com/social/rpc";
    public const string SERVERURL = "http://sandbox.orkut.com/social/rpc";
    public const string CALLBACK = "http://localhost:3896/OrkutAuth/";

    private string _consumerKey = "";
    private string _consumerSecret = "";
    private string _token = "";
    private string _tokenSecret = "";

    #region Properties
    public string ConsumerKey
    {
        get
        {
            if (_consumerKey.Length == 0)
            {
                _consumerKey = ConfigurationManager.AppSettings["OrkutApiKey"];
            }
            return _consumerKey;
        }
        set { _consumerKey = value; }
    }

    public string ConsumerSecret
    {
        get
        {
            if (_consumerSecret.Length == 0)
            {
                _consumerSecret = ConfigurationManager.AppSettings["OrkutSecretKey"];
            }
            return _consumerSecret;
        }
        set { _consumerSecret = value; }
    }

    public string Token { get { return _token; } set { _token = value; } }
    public string TokenSecret { get { return _tokenSecret; } set { _tokenSecret = value; } }
    #endregion
    /// <summary>
    /// Request to Get Authorization Link
    /// </summary>
    /// <returns></returns>
    public string AuthorizationLinkGet()
    {
        string ret = null;
        Method method = Method.GET;
        string url = REQUEST_TOKEN;
        string postData = String.Empty;
        string callback = CALLBACK;
        string scope = SCOPE;

        Uri uri = new Uri(url);

        string nonce = this.GenerateNonce();
        string timeStamp = this.GenerateTimeStamp();

        string sig = getSignatureBase(method.ToString(), url, callback, ConsumerKey, nonce, timeStamp, String.Empty, scope);
        sig = getSignatures(sig, ConsumerSecret, TokenSecret);

        string mystring = getUrl(url, callback, scope, String.Empty, ConsumerKey, timeStamp, nonce, sig);

        string response = WebRequest(method, mystring, postData);

        if (response.Length > 0)
        {
            NameValueCollection qs = HttpUtility.ParseQueryString(response);
            if (qs["oauth_token"] != null)
            {
                this.Token = qs["oauth_token"];
                this.TokenSecret = qs["oauth_token_secret"];
                ret = AUTHORIZE + "?oauth_token=" + this.Token + "&scope=" + UrlEncode(SCOPE);
            }
        }
        return ret;
    }

    /// <summary>
    /// Get AccessToken and TokenSecret For the User
    /// </summary>
    /// <param name="authToken">Authorization Token Returned from the Orkut</param>
    public void AccessTokenGet(string authToken)
    {
        this.Token = authToken;

        Method method = Method.GET;
        string url = ACCESS_TOKEN;
        string postData = String.Empty;

        string outUrl = "";
        string querystring = "";

        Uri uri = new Uri(url);

        string nonce = this.GenerateNonce();
        string timeStamp = this.GenerateTimeStamp();

        string sig = this.GenerateSignature(uri, this.ConsumerKey, this.ConsumerSecret, this.Token, this.TokenSecret, method.ToString(), timeStamp, nonce, out outUrl, out querystring);

        querystring += "&oauth_signature=" + HttpUtility.UrlEncode(sig);

        outUrl += "?";

        string response = WebRequest(method, outUrl + querystring, postData);

        if (response.Length > 0)
        {
            NameValueCollection qs = HttpUtility.ParseQueryString(response);

            if (qs["oauth_token"] != null)
            {
                this.Token = qs["oauth_token"];
                HttpContext.Current.Session["token"] = this.Token;
            }
            if (qs["oauth_token_secret"] != null)
            {
                this.TokenSecret = qs["oauth_token_secret"];
                HttpContext.Current.Session["tokensecret"] = this.Token;
            }
        }
    }

    /// <summary>
    /// Post Data on Orkut
    /// </summary>
    /// <param name="accessToken">User Access Token</param>
    /// <param name="tokenSecret">User Token Secret</param>
    /// <param name="postData">JSON Data to be Requested</param>
    /// <returns></returns>
    public string postWebRequest(string accessToken, string tokenSecret, string postData)
    {
        string nonce = this.GenerateNonce();
        string timeStamp = this.GenerateTimeStamp();

        string url = SERVERURL;
        string method = "POST";

        string sig = getSignatureBase(method, url, String.Empty, ConsumerKey, nonce, timeStamp, accessToken, String.Empty);
        sig = getSignatures(sig, ConsumerSecret, tokenSecret);

        string mystring = getUrl(url, String.Empty, String.Empty, accessToken, ConsumerKey, timeStamp, nonce, sig);

        string response = WebRequest(Method.POST, mystring, postData);

        return response;
    }

    /// <summary>
    /// Generature Signature Base 
    /// </summary>
    /// <param name="method">Method</param>
    /// <param name="url">Url</param>
    /// <param name="callback">Callback Url</param>
    /// <param name="consumerKey">Consumer Key</param>
    /// <param name="nonce">One Time key</param>
    /// <param name="timeStamp">Time Stamp</param>
    /// <param name="accessToken">Access Token</param>
    /// <param name="scope">Scope where the Url is Pointing to</param>
    /// <returns></returns>
    public string getSignatureBase(string method, string url, string callback, string consumerKey, string nonce, string timeStamp, string accessToken, string scope)
    {
        string param = String.Empty;
        Boolean condition = false;
        if (!String.IsNullOrEmpty(callback))
        {
            param += "oauth_callback=" + pEncode(callback);
            condition = true;
        }
        if (condition)
            param += "&";
        param += "oauth_consumer_key=" + consumerKey;
        param += "&oauth_nonce=" + nonce;
        param += "&oauth_signature_method=HMAC-SHA1";
        param += "&oauth_timestamp=" + timeStamp;
        if (!String.IsNullOrEmpty(accessToken))
            param += "&oauth_token=" + pEncode(accessToken);
        param += "&oauth_version=1.0";
        if (!String.IsNullOrEmpty(scope))
            param += "&scope=" + pEncode(scope);

        string baseString = method + "&" + UrlEncode(url) + "&" + UrlEncode(param);

        return baseString;
    }

    /// <summary>
    /// Double Encode of the Parameters Passed in the Url
    /// </summary>
    /// <param name="val"></param>
    /// <returns></returns>
    public string pEncode(string val)
    {
        return val.Replace(":", "%3A").Replace("/", "%2F").Replace("+", "%20").Replace("*", "%2A").Replace("%7E", "~");
    }

    /// <summary>
    /// Generate Signature Using HMAC-SHA1 Algorithm
    /// </summary>
    /// <param name="sig">Signature Base</param>
    /// <param name="consumerSecret">Consumer Secret Key</param>
    /// <param name="tokenSecret">User TokenSecret</param>
    /// <returns></returns>
    public string getSignatures(string sig, string consumerSecret, string tokenSecret)
    {
        HMACSHA1 hmacsha1 = new HMACSHA1();
        hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncode(consumerSecret), string.IsNullOrEmpty(tokenSecret) ? "" : UrlEncode(tokenSecret)));

        byte[] dataBuffer = System.Text.Encoding.ASCII.GetBytes(sig);
        byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);

        return Convert.ToBase64String(hashBytes);
    }

    /// <summary>
    /// Generate Url to be Requested
    /// </summary>
    /// <param name="url">Base Url</param>
    /// <param name="callback">Callback Url</param>
    /// <param name="scope">Scope Url</param>
    /// <param name="accessToken">Access Token of User</param>
    /// <param name="consumerKey">Consumer Key</param>
    /// <param name="timeStamp">Time Stamp</param>
    /// <param name="nonce">One Time Key</param>
    /// <param name="signature">Signature Generated</param>
    /// <returns></returns>
    public string getUrl(string url, string callback, string scope, string accessToken, string consumerKey, string timeStamp, string nonce, string signature)
    {
        string requestUrl = url + "?";
        if (!String.IsNullOrEmpty(callback))
        {
            requestUrl += "oauth_callback=" + UrlEncode(callback);
            requestUrl += "&scope=" + UrlEncode(scope);
        }
        else
            requestUrl += "oauth_token=" + UrlEncode(accessToken);
        requestUrl += "&oauth_consumer_key=" + consumerKey;
        requestUrl += "&oauth_signature_method=HMAC-SHA1";
        requestUrl += "&oauth_timestamp=" + timeStamp;
        requestUrl += "&oauth_nonce=" + nonce;
        requestUrl += "&oauth_version=1.0";
        requestUrl += "&oauth_signature=" + UrlEncode(signature);

        return requestUrl;
    }

    /// <summary>
    /// Make Request to the Server
    /// </summary>
    /// <param name="method">method to be used</param>
    /// <param name="url">Url</param>
    /// <param name="postData">Data to be Posted</param>
    /// <returns></returns>
    public string WebRequest(Method method, string url, string postData)
    {
        HttpWebRequest webRequest = null;
        StreamReader responseReader = null;
        string responseData = String.Empty;

        webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
        webRequest.Method = method.ToString();

        try
        {
            if (method == Method.POST)
            {
                byte[] buffer = Encoding.ASCII.GetBytes(postData);

                webRequest.ContentType = "application/json";
                webRequest.ContentLength = buffer.Length;
                NameValueCollection myCol = new NameValueCollection();
                myCol.Add("X-Orkut-Client-Lib", "0.1");
                webRequest.Headers.Add(myCol);

                Stream PostData = webRequest.GetRequestStream();
                PostData.Write(buffer, 0, buffer.Length);
                PostData.Close();

            }
            responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
            responseData = responseReader.ReadToEnd();

        }
        catch (Exception ex)
        {
            throw;
        }
        finally
        {
            webRequest.GetResponse().GetResponseStream().Close();
            responseReader.Close();
            responseReader = null;
        }
        webRequest = null;

        return responseData;
    }
}
